home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 2 / Gekikoh Dennoh Club Vol. 2 (Japan) (Track 01).bin / tools / cd2pcmt / source.lzh / cdda2pcm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-02  |  19.4 KB  |  671 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <TNB.H>
  5. #include <pcmlib.h>
  6. #include "cd2pcm.h"
  7. #include "extern.h"
  8.  
  9. static char    *REQUEST_MSG[17] = {
  10.     "No Se(0): 装置には、異常は、なかった\n",
  11.     "Recovered Error (1): 装置自体のリトライ機能によりコマンドが正常に終了した\n",
  12.     "Not Ready (2): 装置自体に異常が発生し、オペレータの介入が必要であることを示"
  13.             "す\n",
  14.     "Medium Error (3): リード/ライト動作時において媒体に起因するエラーが発生し、"
  15.             "リトライでエラーが回復できなかった\n",
  16.     "Hardware Error (4): 装置のハードウェアに障害が発生し、コマンドの実行が正常終"
  17.             "了しなかった\n",
  18.     "Illegal Request(5):イニシエータからのコマンド・データに異常があり、コマンドの"
  19.             "実行ができなかった\n",
  20.     "Unit Attention (6): 装置がリセットされたことを示す。又メディアが入れ換えられた"
  21.             "ことも示す\n",
  22.     "Write Protected (7): ライト・プロテクト状態にあるときにライト動作を含むコマンド"
  23.             "を受け取ったことを示す\n",
  24.     "Blank Check (8): 読みだし中にブランク領域になった。又は、書き込み中にブランク領"
  25.             "域でない領域になった\n",
  26.     "Vendor Unique (9): メーカーごとに自由に使用可\n",
  27.     "Copy Aborted (A): Copy,Compare,Copy & Verifyコマンドがデバイス異常により中止し"
  28.             "た\n",
  29.     "Aborted Command (B): ターゲットがイニシエータからのコマンドをアボートしたこと"
  30.             "を示す\n",
  31.     "Equal (C): Searchコマンドで一致を検出した\n",
  32.     "Volume Overflow (D): データがバッファに残っているのに、デバイスは最終ブロック"
  33.             "に達してしまった\n",
  34.     "Miscompare (E): ソースデータとメディアから読み出したデータが一致しない\n",
  35.     "(F): 将来の拡張用\n",
  36.             "センス・コマンドでエラーが、発生しました。\n"
  37. };
  38.  
  39. static char    MODE_TBL[2][12] = {
  40.     /* SONY CDU-561 モード変更 */
  41.     { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30 },
  42.     /* 東芝 XM-3401TA audio track 2352 byte */
  43.     { 0x00, 0x00, 0x00, 0x08, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30 }
  44. };
  45. static char    MODE_TBL_N[2][12] = {
  46.     /* SONY CDU-561 モードもどし */
  47.     { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 },
  48.     /* 東芝 XM-3401TA audio track 2048 byte */
  49.     { 0x00, 0x00, 0x00, 0x08, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 }
  50. };
  51.  
  52. static char    SPEED_MODE_TBL[3][16] = {
  53.     /* 標準速度 */
  54.     { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30,
  55.       0x31, 0x02, 0x00, 0x00 },
  56.     /* 倍速 */
  57.     { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30,
  58.       0x31, 0x02, 0x01, 0x00 },
  59.     /* 最大速度 */
  60.     { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30,
  61.       0x31, 0x02, 0xff, 0x00 }
  62. };
  63.  
  64. static char    *MODE_MES[3] = {
  65.     "標準速度 ", "倍速 ", "最大速度 "
  66. };
  67.  
  68. unsigned char    erod[2352];    /* errod用ワーク */
  69. unsigned char    work[2352];    /* 1度読みワーク */
  70. unsigned char    work2[2352];    /* 2度読みワーク */
  71. unsigned char    work3[2352];    /* 3度読みワーク */
  72.  
  73. /****************************************************************/
  74. /*        オーディオデータを取り込む            */
  75. /****************************************************************/
  76. void cdda2pcm( int music_no, int tstart, int tend )
  77. {
  78. unsigned char buf[256];            /* ローカルワーク */
  79. int    start,end,leadout_address,sta_t,end_t,lng_t,fc;
  80. int    min,max,ll,sss;
  81. int    len,sense,err_cnt;
  82. int    i,frame_cnt;                /* loop count */
  83. int    buffer_size;
  84. char    *buffer_ptr;                /* バッファアドレス */
  85. int    escchk=0;
  86. int    cvf=0;
  87. unsigned char *pp;
  88.  
  89. /*--- PCMLIB 初期化 ---*/
  90. PCMFREQ_INIT();        //PCMFREQ();
  91. PCMFFREQ_INIT();    //PCMFFREQ();
  92. PCMFREQVOL_INIT();    //PCMFREQVOL();
  93. PCMFFREQVOL_INIT();    //PCMFFREQVOL();
  94. P162PCM_INIT();        //P162PCM();
  95. PTOA_MAKE_BUFFER();    //PTOA_EXEC();
  96. PTOA_INIT();
  97.  
  98. trans_size=0;            /* 転送サイズ */
  99. trans_time=0;            /* 転送のみ時間 */
  100.  
  101. /*--- 取り込みモード変更 ---*/
  102. //S_MODESENSE( 0x3f, 12, SCSI_ID, MT_bak );
  103. i=S_MODESELECT( PF, 12, SCSI_ID, MODE_TBL[CDROM_DRIVE] );
  104. if ( i==2 ){
  105.     if ( S_REQUEST( 22, SCSI_ID, buf ) == 0 )
  106.         sense = (unsigned int)( buf[2] & 0x0f );
  107.     else    sense = 16;
  108.     if ( sense!=6 ){
  109.         printf("Check Condition!! Sense Key=%d(ASC=%02X,ASCQ=%02X)\n",sense,buf[12],buf[13]);
  110.         printf( REQUEST_MSG[sense] );
  111.         if ( inqu_sw!=0 && CDROM_DRIVE==TOSHIBATYPE )
  112.             printf(" TOSHIBA系 Read CD-DA コマンドはサポートしていないようです。\n");
  113.         if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  114.             EndtDisp(1);
  115.     }
  116. } else if ( i!=0 ){
  117.     printf("エラーが出ました。モードは変更出来ませんでした。\n");
  118.     if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  119.         EndtDisp(1);
  120. }
  121. /*--- 取り込み速度変更(MMC) ---*/
  122. if ( cdspeed>0 ){
  123.     i=SetSpeed( 706*cdspeed/4 );
  124.     if ( i!=0 )
  125.         printf("Set Speed Command でエラーが出ました。\n");
  126.     if ( i==2 ){
  127.         if ( S_REQUEST( 22, SCSI_ID, buf ) == 0 )
  128.             sense = (unsigned int)( buf[2] & 0x0f );
  129.         else    sense = 16;
  130.         if ( sense==5 ){
  131.             if ( buf[12]==0x20 )
  132.                 printf("この CD-ROM ドライブが対応していない可能性があります。\n");
  133.             else    printf("この CD-ROM ドライブの対応範囲を越えている可能性があります。\n");
  134.             if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  135.                 EndtDisp(1);
  136.         } else if ( sense!=6 ){
  137.             printf("Check Condition!! Sense Key=%d(ASC=%02X,ASCQ=%02X)\n",sense,buf[12],buf[13]);
  138.             printf( REQUEST_MSG[sense] );
  139.             if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  140.                 EndtDisp(1);
  141.         }
  142.     } else if ( i!=0 ){
  143.         if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  144.             EndtDisp(1);
  145.     }
  146. }
  147. /*--- SONY系 アクセス速度変更 ---*/
  148. if ( cd_speed != -1 && CDROM_DRIVE == CD_CDU561 ){
  149.     /* CD 速度変更 */
  150.     i=S_MODESELECT( PF, 16, SCSI_ID, SPEED_MODE_TBL[cd_speed] );
  151.     if ( i==0 ){
  152.         printf("CD-ROMアクセス速度は、");
  153.         printf(MODE_MES[cd_speed]);
  154.         printf("に変更されました。\n");
  155.     } else if ( i==2 ){
  156.         if ( S_REQUEST( 22, SCSI_ID, buf ) == 0 )
  157.             sense = (unsigned int)( buf[2] & 0x0f );
  158.         else    sense = 16;
  159.         if ( sense!=6 ){
  160.             printf("Check Condition!! Sense Key=%d(ASC=%02X,ASCQ=%02X)\n",sense,buf[12],buf[13]);
  161.             printf( REQUEST_MSG[sense] );
  162.             if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  163.                 EndtDisp(1);
  164.         }
  165.     } else {
  166.         printf("エラーが出ました。モードは変更出来ませんでした。\n");
  167.         if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  168.             EndtDisp(1);
  169.     }
  170. }
  171.  
  172. /*--- メモリーのチェック ---*/
  173. len = 2352;                /* 44.1 kHz 16 bit streo 1/75 s */
  174. buffer_size = (int)MALLOC( 0x00ffffff );
  175. buffer_size = buffer_size & 0x00ffffff;
  176. if ( buffer_size < len ){
  177.     /* メモリが全然足らん */
  178.     printf("メモリーが、足りないので、実行できません。\n");
  179.     EndtDisp(1);
  180. }
  181. /*--- メモリー確保 ---*/
  182. buffer_ptr = MALLOC( buffer_size );    /* エラーが返ってこない */
  183. if ( pcm_mode!=CONVERT_A88 ){
  184.     frame_cnt = (buffer_size-2) / len ;        /* フレーム数を求める */
  185. } else {
  186.     frame_cnt = ((buffer_size-2) / len)/4 ;        /* フレーム数を求める */
  187. }
  188. if ( buf_size != -1 ){
  189.     buf_size = buf_size * 75;        /* 指定されたフレーム数 */
  190.     if ( buf_size > frame_cnt ){
  191.         printf(" %d秒分のメモリが確保出来ませんでした。\n",buf_size/75);
  192.         printf(" %d秒分のメモリで処理を行います。\n",frame_cnt/75);
  193.     } else
  194.         frame_cnt = buf_size;
  195. }
  196. CDPCM_ptr  = buffer_ptr;                /* CD のバッファアドレスセット */
  197. CDPCMM_ptr = CDPCM_ptr+((buffer_size/2)&0xFFFFFFFE);    /* monoになった時うしろ半分はワークに*/
  198. /*--- CD をチェック! ---*/
  199. if ( RedTOC( &leadout_address, &min, &max ) != 0 ){
  200.     printf(" Read TOC でエラーが、でました。\n");
  201.     EndtDisp(1);
  202. }
  203. /*--- 取り込みアドレス計算 ---*/
  204. if ( music_no == -1 ){
  205.     if ( adr2time(leadout_address) - 1 < tstart ){
  206.         printf("読み込み開始時間の設定が大きすぎます。\n");
  207.         EndtDisp(1);
  208.     }
  209.     if ( tend == -1 )
  210.         tend = adr2time(leadout_address) -1;
  211.     if ( adr2time(leadout_address) -1 +1 < tend ){
  212.         printf("読み込み終了時間の設定が大きすぎます。\n");
  213.         EndtDisp(1);
  214.     }
  215.     start = tstart;
  216.     end   = tend + 1;
  217. } else {
  218.     if ( Music_inf( music_no, &start ) != 0 ){
  219.         printf(" Music_inf でエラーが、でました。\n");
  220.         EndtDisp(1);
  221.     }
  222.     start = adr2time( start );
  223.     if ( music_no == max ){
  224.         end   = adr2time( leadout_address )-1;
  225.     } else {
  226.         if ( Music_inf( music_no+1 , &end ) != 0 ){
  227.             printf("Start Track Address or ReadTOC Command error のため読み込み出来ませんでした。\n");
  228.             EndtDisp(1);
  229.         }
  230.         end   = adr2time( end );
  231.     }
  232. }
  233.  
  234. /*--- ファイルを作成する ---*/
  235. if ( test_fg==0 && merc_fg==0 ){
  236.     hdl = CREATE( outfile, 0x20 );
  237.     if ( hdl < 0 ){
  238.         printf("ファイルの作成に失敗しました。\n");
  239.         printf("errcode = %d\n",hdl );
  240.         EndtDisp(1);
  241.     }
  242.     if ( adpcm_flg == 2 ){
  243.         /*-- WAV のヘッダ制作 --*/
  244.         char    buf[64];
  245.         WRITE(hdl,buf,44);    //ゴミを書いておく
  246.     }
  247. } else {
  248.     if ( merc_fg ){
  249.         printf(" まーきゅりー演奏 mode\n");
  250.     } else {
  251.         printf(" Read CD-DA test mode\n");
  252.     }
  253. }
  254. write_size = 0;                /* DISKに書き込んだサイズ*/
  255. C_CUROFF();        /* カーソルを消去する */
  256. printf("\x1B""0");
  257. /*------ オーディオデータ取り込む ------*/
  258. sta_t    = bin2time( start + 75 * 2 );
  259. end_t    = bin2time( end + 75 * 2 -1 );
  260. lng_t    = bin2time( (end-start) );
  261. if ( music_no != -1 ){
  262.     char    *s;
  263.     if ( CDC_ID==SCSI_ID )
  264.         s=CDCTNAME(music_no);
  265.     else    s=0;
  266.     if ( s==0 )
  267.         printf(" %d 曲目を読み込みます。\n",music_no );
  268.     else    printf(" %d 曲目[%s]を読み込みます。\n",music_no,NameCenter(s) );
  269. }
  270. printf("取込時間 %2d分%02d秒%02d~%2d分%02d秒%02d (%2d分%02d秒%02d)\n\n",
  271.     ( sta_t >> 16 ) & 0xff, ( sta_t >> 8 ) & 0xff, sta_t & 0xff,
  272.     ( end_t >> 16 ) & 0xff, ( end_t >> 8 ) & 0xff, end_t & 0xff,
  273.     ( lng_t >> 16 ) & 0xff, ( lng_t >> 8 ) & 0xff, lng_t & 0xff
  274. );
  275. srand(ONTIME());
  276. memset( buf, 0x00, 12 );
  277. sss=start;
  278. cvf=0;
  279. if ( pcm_mode!=0 && pcm_mode!=CONVERT_PCMA )
  280.     sct_fg = 0;            /* SCSITAI 使用フラグ*/
  281. for(i=0;start<end;){
  282.     pp=(unsigned char*)&CDPCM_ptr[i*2352];
  283.     if ( dma_fg!=0 && mach2_fg==0 && (pcm_mode==0 || pcm_mode==CONVERT_PCMA) ){
  284.         // DMA 転送で Mach2 でなくて pcms | pcma の時
  285.         pp++;        // 奇数に(笑)
  286.     }
  287.     CURDRV();
  288.     if ( CDROM_DRIVE == CD_CDU561 ){
  289.         /* SONY CDU-561 音声トラック読み込みコマンド */
  290.         buf[0] = 0xd8;            // 1101_1000  グループ 6
  291.         buf[2] = (start >> 24)&0xff;
  292.         buf[3] = (start >> 16)&0xff;
  293.         buf[4] = (start >>  8)&0xff;
  294.         buf[5] = (start      )&0xff;
  295.         buf[8] = 0;
  296.         buf[9] = 1;        /* 1 block */
  297.     } else {
  298.         /* 東芝 XM-3401TA 音声トラック読み込みコマンド */
  299.         buf[0] = 0x28;        // 拡張リードコマンド 0010_8000  グループ 1
  300.         buf[2] = (start >> 24)&0xff;
  301.         buf[3] = (start >> 16)&0xff;
  302.         buf[4] = (start >>  8)&0xff;
  303.         buf[5] = (start      )&0xff;
  304.         buf[7] = 0;
  305.         buf[8] = 1;        /* 1 block */
  306.     }
  307.     sta_t = bin2time( start + 75 * 2 );
  308.     if ( check_fg == 0 ){
  309.         printf_( CFC CUP );
  310.         /*--- 読み込む ---*/
  311.         if ( secone_fg==0 ){
  312.             ll=(end-start);
  313.             if ( ll>65535 )
  314.                 ll=65535;
  315.             if ( ll>(frame_cnt-i) ){
  316.                 ll=(frame_cnt-i);
  317.                 cvf=1;
  318.             }
  319.             if ( CDROM_DRIVE == CD_CDU561 ){
  320.                 buf[8]=ll/0x100;
  321.                 buf[9]=ll&0xFF;
  322.             } else {
  323.                 buf[7]=ll/0x100;
  324.                 buf[8]=ll&0xFF;
  325.             }
  326.             end_t = bin2time( start+75*2+ll-1 );
  327.             lng_t = bin2time( ll );
  328.             printf_("処理時間 %2d分%02d秒%02d~%2d分%02d秒%02d (%2d分%02d秒%02d)\n",
  329.                 ( sta_t >> 16 ) & 0xff, ( sta_t >> 8 ) & 0xff, sta_t & 0xff,
  330.                 ( end_t >> 16 ) & 0xff, ( end_t >> 8 ) & 0xff, end_t & 0xff,
  331.                 ( lng_t >> 16 ) & 0xff, ( lng_t >> 8 ) & 0xff, lng_t & 0xff
  332.             );
  333.             printf_(" ★Read CD-DA" CFC "\n" CUP);
  334.         } else {
  335.             ll=1;
  336.             printf_("処理時間 %2d分%02d秒%02d\n",
  337.                 ( sta_t >> 16 ) & 0xff, ( sta_t >> 8 ) & 0xff, sta_t & 0xff
  338.             );
  339.         }
  340.  
  341. //        if ( mbr7f )
  342. //            l1=3;
  343. //        else    l1=1;
  344. //        for(;l1>0;l1--)
  345. //            ReadCDDA(12, buf, 2352*ll,pp);
  346.  
  347.         if ( mbr7f ){
  348.             S_REZEROUNIT(SCSI_ID);
  349.             S_SEEK(0,SCSI_ID);
  350.         }
  351.  
  352.         ReadCDDA(12, buf, 2352*ll,pp);
  353.  
  354.     } else {
  355.         printf_( CUP );
  356.         /*--- チェックしながら読み込む ---*/
  357.         printf_("処理時間 %2d分%02d秒%02d\n",
  358.             ( sta_t >> 16 ) & 0xff, ( sta_t >> 8 ) & 0xff, sta_t & 0xff
  359.         );
  360.         ll=1;
  361.         err_cnt = 1;
  362.         ReadCDDA(12,buf,2352,work);
  363.         for(;;)    {
  364.             while( (BITSNS(0xA)&(1<<5))!=0 );    //[XF1]押されていたら待つ
  365.             ReadCDDA(12,buf,2352,work2);
  366.             if ( check_fg==1 ){
  367.                 fc=memfcmp( work, work2, 2352 ,fcmppr );
  368.                 if ( fc==0 ){
  369.                     printf_(" ★1度目と2度目が一致しました。%d回目" CFC "\n" CUP,err_cnt);
  370.                     memcpy( pp,work,2352 );
  371.                     break;
  372.                 } else if ( fc==1 ){
  373.                     printf_(" ★1度目と2度目が%d%一致しました。%d回目" CFC "\n" CUP,fcmppr,err_cnt);
  374.                     memcpy( pp,work,2352 );
  375.                     break;
  376.                 }
  377.             }
  378.             if ( err_cnt>=40 ){
  379.                 WW((rand()%50)+8);
  380.             } else if ( err_cnt>=20 && (err_cnt%8)==0 ){
  381.                 /*8回に1回休み*/
  382.                 WW(45);
  383.             }
  384.             while( (BITSNS(0xA)&(1<<5))!=0 );    //[XF1]押されていたら待つ
  385.             ReadCDDA(12,buf,2352,work3);
  386.             if ( check_fg==1 ){
  387.                 fc=memfcmp( work, work3, 2352,fcmppr );
  388.                 if ( fc== 0 ){
  389.                     printf_(" ★1度目と3度目が一致しました。%d回目" CFC "\n" CUP,err_cnt);
  390.                     memcpy( pp,work,2352 );
  391.                     break;
  392.                 } else if ( fc== 1 ){
  393.                     printf_(" ★1度目と3度目が%d%一致しました。%d回目" CFC "\n" CUP,fcmppr,err_cnt);
  394.                     memcpy( pp,work,2352 );
  395.                     break;
  396.                 }
  397.                 fc=memfcmp( work2, work3, 2352,fcmppr );
  398.                 if ( fc== 0 ){
  399.                     printf_(" ★2度目と3度目が一致しました。%d回目" CFC "\n" CUP,err_cnt);
  400.                     memcpy( pp,work2,2352 );
  401.                     break;
  402.                 } else if ( fc== 1 ){
  403.                     printf_(" ★3度目と3度目が%d%一致しました。%d回目" CFC "\n" CUP,fcmppr,err_cnt);
  404.                     memcpy( pp,work,2352 );
  405.                     break;
  406.                 }
  407.             } else {
  408.                 //マニアック向け
  409.                 if ( memfcmp( work,work2,2352,fcmppr )==0 && memfcmp( work,work3,2352,fcmppr )==0 ){
  410.                     printf_(" ★3つ連続で一致しました。%d回目" CFC "\n" CUP,err_cnt);
  411.                     memcpy( pp,work,2352 );
  412.                     break;
  413.                 }
  414.             }
  415.             err_cnt++;
  416.             if ( check_fg==1 && err_cnt>=5+1 && (BITSNS(0xE)&1)==0 ){
  417.                 printf_(" ★リトライオーバーです。最初のデータを有効とします。" CFC "\n" CUP);
  418.                 memcpy( pp, work,2352 );
  419.                 break;
  420.             }
  421.             printf_(" ★Checking...%5d回目"CFC"\n"CUP,err_cnt);
  422.             memcpy( work,work3,2352 );
  423.             if ( err_cnt>=40 ){
  424.                 WW((rand()%68)+8);
  425.             } else if ( err_cnt>=20 ){
  426.                 if ( (err_cnt%4)==0 ){
  427.                     /*4回に1回休み*/
  428.                     WW(68);
  429.                 }
  430.             } else if ( err_cnt>=10 && (err_cnt%10)==0 ){
  431.                 /*10回に1回休み*/
  432.                 WW(68);
  433.             }
  434.             if ( (BITSNS(0)&2)!=0 ){    //[ESC]押されていたら
  435.                 escchk=1;
  436.                 break;
  437.             }
  438.         }
  439.         if ( escchk!=0 )
  440.             break;
  441.     }
  442.     i+=ll;
  443.     if ( (BITSNS(0)&2)!=0 ){    //[ESC]押されていたら
  444.         escchk=1;
  445.         break;
  446.     }
  447.     if ( i==frame_cnt || cvf ){
  448.         len = 2352*i;
  449.         i = 0;
  450.         convert( len );
  451.         cvf=0;
  452.     }
  453.     start+=ll;
  454.     if ( (BITSNS(0)&2)!=0 ){    //[ESC]押されていたら
  455.         escchk=1;
  456.         break;
  457.     }
  458. }
  459. printf("\x1B""1");
  460. if ( escchk!=0 )
  461.     printf( CUP CFC " ☆☆☆読み込みを中止します。\n");
  462. if ( i!=0 ){
  463.     /* 残りを書き込む */
  464.     len = 2352 * i;
  465.     convert( len );
  466. }
  467. if ( adpcm_flg==2 && test_fg==0 ){
  468.     /*-- WAV のヘッダ補正 --*/
  469.     static char header1[]= "RIFF";
  470.     static char header2[]={
  471.          'W', 'A', 'V', 'E', 'f',  'm', 't',0x20,0x10,0x00,
  472.         0x00,0x00,0x01,0x00,0x01, 0x00,0x22,0x56,0x00,0x00,
  473.         0x22,0x56,0x00,0x00,0x01, 0x00,0x08,0x00, 'd', 'a',
  474.          't', 'a'
  475.     };
  476.     char buf[8];
  477.     int    j;
  478.     header2[20-8]=1;    /*1=PCM  0x20=ADPCM */
  479.     header2[22-8]=2;    /*1=モノラル 2=ステレオ*/
  480.     header2[34-8]=0x10;    /*0x08=8ビット 0x10=16ビット*/
  481.     header2[32-8]=1;    /*わからない ;_; */
  482.     /*サンプリング周波数*/
  483.     header2[24-8]= pcm_rate & 0xFF;
  484.     header2[25-8]= pcm_rate / 0x100;
  485.     j = write_size + 36;
  486.     SEEK( hdl, 0, 0);
  487.     WRITE( hdl,header1,4);
  488.     buf[0]=  j        & 0xff;
  489.     buf[1]= (j >>  8) & 0xff;
  490.     buf[2]= (j >> 16) & 0xff;
  491.     buf[3]= (j >> 24) & 0xff;
  492.     WRITE(hdl,buf,4);
  493.     WRITE(hdl,header2,32);
  494.     buf[0]= write_size        & 0xff;
  495.     buf[0]=(write_size >>  8) & 0xff;
  496.     buf[0]=(write_size >> 16) & 0xff;
  497.     buf[0]=(write_size >> 24) & 0xff;
  498.     WRITE(hdl,buf,4);
  499. }
  500. if ( test_fg==0 ){
  501.     CLOSE( hdl );
  502.     printf( CUP CFC "\nオーディオデータの読み込みは");
  503. } else {
  504.     printf( CUP CFC "\nオーディオデータのテスト読みは");
  505. }
  506. if ( escchk==0 ){
  507.     printf("終了しました。\n");
  508. } else {
  509.     printf("途中終了しました。\n");
  510.     while( (BITSNS(0)&2)!=0 );    //[ESC]押されていたら待つ
  511. }
  512. if ( retry_fg!=0 ){        /* -retry[n] 読み込みエラーが出た場合[n]回挑戦*/
  513.     if ( retry_mx>1 )
  514.         printf("    最大リトライ数 %d\n",retry_mx);
  515. }
  516. if ( errjmp_fg!=0 ){            /* 致命的でないエラーは無視します。*/
  517.     printf("    非致命的エラー数 %d\n",errjmp_mx);
  518. }
  519. /* 時間を表示 */
  520. if ( trans_time>50 && secone_fg==0 ){
  521.     printf(" ★Read CD-DA :  %.1fKB/s  < %.2f倍速 >\n",
  522.         (((double)trans_size)*100.*150)/(((double)trans_time)*75.),
  523.         (((double)trans_size)*100.)/(((double)trans_time)*75.)
  524.     );
  525. }
  526. C_CURON();
  527. /*---ブロックサイズを戻す---*/
  528. i=S_MODESELECT( PF, 12, SCSI_ID, MODE_TBL_N[CDROM_DRIVE] );
  529. if ( i==2 ){
  530.     if ( S_REQUEST( 22, SCSI_ID, buf ) == 0 )
  531.         sense = (unsigned int)( buf[2] & 0x0f );
  532.     else    sense = 16;
  533.     if ( sense!=6 ){
  534.         printf("Check Condition!! Sense Key=%d(ASC=%02X,ASCQ=%02X)\n",sense,buf[12],buf[13]);
  535.         printf( REQUEST_MSG[sense] );
  536.         //if ( inqu_sw!=0 && CDROM_DRIVE==TOSHIBATYPE )
  537.         //    printf(" TOSHIBA系 Read CD-DA コマンドはサポートしていないようです。\n");
  538.         //if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  539.         //    EndtDisp(1);
  540.     }
  541. } else if ( i!=0 ){
  542.     printf("エラーが出ました。ブロックサイズが変更されたままです。\n");
  543.     //if ( errjmp_fg==0 )        /* 致命的でないエラーは無視します。*/
  544.     //    EndtDisp(1);
  545. }
  546. SetSpeed( 0xFFFF );        // 最大速度にしておく。
  547. }
  548. /*++*/
  549. void    WW(int w)    // 1/100s
  550. {
  551. int    i,j;
  552. i=ONTIME();
  553. for(;;){
  554.     if ( (j=ONTIME()-i)<0 )
  555.          j+=8639999;
  556.     if ( j>=w )
  557.         break;
  558. }
  559. }
  560. /****************************************/
  561. /*    READ CD-DA            */
  562. /****************************************/
  563. void    ReadCDDA(cml,com,lg,ad)
  564. int    cml,lg;
  565. char    *com,*ad;
  566. {
  567. int    i,n,l,rc,sense,b,i8;
  568. unsigned char    buf[256];
  569. int    t1,t2;
  570. n=retry_fg;
  571. sense=-1;
  572. if ( n<=0 ) n=1;
  573. for(l=0;l<n;l++){
  574.     for(i8=0;i8<10;i8++){
  575.         b=BREAKCK(-1);
  576.         BREAKCK(2);
  577.         t1=ONTIME();    // 開始時間
  578.         rc=scsi_cmd__(cml,com,lg,ad);
  579.         t2=ONTIME();    // 終了時間
  580.         BREAKCK(b);
  581.         if ( rc!=8 )
  582.             break;
  583.     }
  584.     if ( rc==0 ){
  585.         //問題無し
  586.         if ( errjmp_fg && errod_fg && secone_fg )
  587.             memcpy( erod,ad,2352 );
  588.         if ( retry_mx<l )
  589.             retry_mx=l;        /* エラーの最大リトライ数 */
  590.         trans_size+=(lg/2352);            /* 転送サイズ */
  591.         i=t2-t1;
  592.         if ( i<0 )
  593.             i+=8640000;
  594.         trans_time+=i;            /* 転送のみ時間 */
  595.         return;
  596.     }
  597.     if ( rc==0x02 ){
  598.         /* チェック・コンディション */
  599.         if ( S_REQUEST( 22, SCSI_ID, buf ) == 0 )
  600.             sense = (unsigned int)( buf[2] & 0x0f );
  601.         else    sense = 16;
  602.         if ( sense==0xB || sense==0x6 ){
  603.                     //0x0B ; ターゲットはコマンドの実行を異
  604.                     //    常終了したはスルー(PD-DRIVE以外
  605.                     //    で出たのはしらない)
  606.                     //0x06 ; 交換されていたらでる。問題なし
  607.             if ( errjmp_fg && errod_fg && secone_fg )
  608.                 memcpy( erod,ad,2352 );
  609.             if ( retry_mx<l )
  610.                 retry_mx=l;        /* エラーの最大リトライ数 */
  611.             n++;
  612.             continue;
  613.         } else {
  614.             printf("\nCheck Condition!! Sense Key=%d(ASC=%02X,ASCQ=%02X)\n",sense,buf[12],buf[13]);
  615.         }
  616.     } else {
  617.         sense=-1;
  618.         if ( inqu_sw!=0 && CDROM_DRIVE==CD_CDU561 )
  619.             printf(" \nSONY系 Read CD-DA コマンドはサポートしていないようです。  (%d回)\n" CUP CUP,l+1);
  620.         else    printf_("\nRead CD-DA Command Err!!   (%d回)\n" CUP CUP,l+1);
  621.     }
  622.     if ( mbr7f ){
  623.         S_REZEROUNIT(SCSI_ID);
  624.         S_SEEK(0,SCSI_ID);
  625.     }
  626. }
  627. if ( errjmp_fg ){        /* 致命的でないエラーは無視します。*/
  628.     errjmp_mx++;            /* 致命的でないエラーの数 */
  629.     /*エラーなので、00を埋めて返す*/
  630.     if ( errod_fg && secone_fg ){
  631.         memcpy( ad,erod,2352 );
  632.         return;
  633.     }
  634.     memset( ad, 0x00, lg );
  635.     return;
  636. }
  637. printf("\n\n");
  638. if ( sense>=0 )
  639.     printf( REQUEST_MSG[sense] );
  640. if ( test_fg==0 )
  641.     CLOSE(hdl);
  642. EndtDisp(1);
  643. }
  644. /*************************************
  645.     内容比較
  646. [戻り値] 0 ; 一致
  647.     -1 ; 全然違う
  648.      1 ; n%一致
  649. *************************************/
  650. int    memfcmp(ad1,ad2,l,n)
  651. unsigned char *ad1,*ad2;
  652. int    l,n;
  653. {
  654. int    ll,ep;
  655. ll=l;
  656. ep=0;
  657. for(;l>0;l--){
  658.     if ( *ad1++==*ad2++ ){
  659.         ep++;
  660.     } else {
  661.         if ( n==0 )
  662.             return(-1);
  663.     }
  664. }
  665. if ( ep==ll )
  666.     return(0);
  667. if ( ep*100/ll>n )
  668.     return(1);
  669. return(-1);
  670. }
  671.